home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
smaltalk
/
manchest.lha
/
MANCHESTER
/
manchester
/
4.1
/
BetterRandom.st
< prev
next >
Wrap
Text File
|
1993-07-24
|
4KB
|
136 lines
" NAME BetterRandom
AUTHOR Bernard Horan <bernard@is.morgan.com>
CONTRIBUTOR Bernard Horan <bernard@is.morgan.com>
FUNCTION Improved Random number interface
ST-VERSIONS 4.1
PREREQUISITES
CONFLICTS
DISTRIBUTION global
VERSION 2.0
DATE March 1993
SUMMARY I've never been happy with the implmentation
of Random, since I don't see why it's the clients responsibility to
transform a 'raw' float between 0 and 1 to a number (or element) from
some specified range.
The other approach is to send a message to an instance of Random, asking for
an element within a range, providing some parameters as arguments to the
message.
Personally, I feel that it's the responsibility of the instance of
Random to simply provide the another random element when asked for its
"next", and that the instance of Random should be created with the
appropriate parameters so it can do so.
In this light, I've implemented a subclass of Random, called BetterRandom,
it follows below. Let me know what you think of it.
Bern"
'From Objectworks\Smalltalk(R), Release 4.1 of 15 April 1992
ENVY/Developer R1.40 of 21 August 1992 on 1 March 1993 at 11:48:01 am'!
Random subclass: #BetterRandom
instanceVariableNames: 'transformBlock '
classVariableNames: ''
poolDictionaries: ''
category: 'New-Random'!
!BetterRandom methodsFor: 'accessing'!
next
"return the next random number, having transformed it by the block"
^transformBlock value: super next! !
!BetterRandom methodsFor: 'private'!
initialize
"emulate my super"
self transformBlock: [:x | x]!
transformBlock: aBlock
"aBlock should be a one-argument block -- the argument is the 'raw' random number"
transformBlock := aBlock! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
BetterRandom class
instanceVariableNames: ''!
!BetterRandom class methodsFor: 'examples'!
exampleCollection1
"Interval as argument"
"BetterRandom exampleCollection1"
| rand |
rand := BetterRandom fromCollection: (1 to: 13 by: 0.7).
10 timesRepeat: [Transcript show: rand next printString; cr]!
exampleCollection2
"SequenceableCollection as argument"
"BetterRandom exampleCollection2"
| rand |
rand := BetterRandom fromCollection: ColorValue constantNames.
10 timesRepeat: [Transcript show: rand next printString; cr]!
exampleCollection3
"Set as argument"
"BetterRandom exampleCollection3"
| rand |
rand := BetterRandom fromCollection: Object subclasses.
10 timesRepeat: [Transcript show: rand next printString; cr]!
exampleFloat
"BetterRandom exampleFloat"
| rand |
rand := BetterRandom floatBetween: 4 and: 13.
10 timesRepeat: [Transcript show: rand next printString; cr]!
exampleInteger
"BetterRandom exampleInteger"
| rand |
rand := BetterRandom integerBetween: 4 and: 13.
10 timesRepeat: [Transcript show: rand next printString; cr]! !
!BetterRandom class methodsFor: 'instance creation'!
floatBetween: start and: stop
| size |
size := stop - start.
size > 0 ifFalse: [^self error: 'non-positive range'].
^self fromBlock: [:x | x * size + start ]!
fromBlock: aBlock
"aBlock should be a one-argument block -- the argument is the 'raw' random number"
^self new transformBlock: aBlock!
fromCollection: aCollection
"Create an instance of me which will return a random element from the
argument"
| size aSequenceableCollection |
aSequenceableCollection := aCollection isSequenceable ifFalse: [aCollection asOrderedCollection]
ifTrue: [aCollection].
size := aSequenceableCollection size.
size > 0 ifFalse: [^self error: 'Empty collection'].
^self
fromBlock:
[:x |
| index |
index := (x * size + 1) truncated.
aSequenceableCollection at: index]!
integerBetween: start and: stop
| size |
size := stop - start.
size > 0 ifFalse: [^self error: 'non-positive range'].
^self fromBlock: [:x | (x * size + start) truncated]!
new
^super new initialize! !